package com.dd.cloud.user.DTO;

import com.alibaba.fastjson.JSON;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.user.DTO.common.CommonExpressReportReq;
import com.dd.cloud.user.DTO.common.CommonStatusReportReq;
import com.dd.cloud.user.DTO.dsl.DslExpressReportReq;
import com.dd.cloud.user.DTO.dsl.DslStatusReportReq;
import com.dd.cloud.user.DTO.hjt.HjtStatusReportReq;
import com.dd.cloud.user.DTO.hst.HstExpressReportReq;
import com.dd.cloud.user.DTO.km.KmExpressReportReq;
import com.dd.cloud.user.DTO.km.KmStatusReportReq;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Enumeration;

/**
 * @author Lx
 * @version 1.0
 * @date 2023/8/16
 */
@Data
@Slf4j
public class CommonParamReq implements Serializable {

    private static final long serialVersionUID = -5939523420138266216L;

    private String flag;

    private HttpServletRequest request;

    public CommonParamReq() {
    }

    public CommonParamReq(String flag, HttpServletRequest request) {
        this.flag = flag;
        this.request = request;
    }

    public CommonParamReq toStatusPojo(String flag, HttpServletRequest request) {
        switch (flag) {
            case FlagConstant.HJT:
                return generateData(request, FormatConstant.POST_JSON, HjtStatusReportReq.class);
            case FlagConstant.DSL:
                return generateData(request, FormatConstant.GET, DslStatusReportReq.class);
            case FlagConstant.KM:
                return generateData(request, FormatConstant.GET, KmStatusReportReq.class);
            case FlagConstant.COMMON:
                return generateData(request, FormatConstant.GET, CommonStatusReportReq.class);
            default:
                throw new ZekeException(400, "未知药房标识");
        }
    }

    public CommonParamReq toExpressPojo(String flag, HttpServletRequest request) {
        switch (flag) {
            case FlagConstant.DSL:
                return generateData(request, FormatConstant.GET, DslExpressReportReq.class);
            case FlagConstant.KM:
                return generateData(request, FormatConstant.GET, KmExpressReportReq.class);
            case FlagConstant.HST:
                return generateData(request, FormatConstant.POST_JSON, HstExpressReportReq.class);
            case FlagConstant.COMMON:
                return generateData(request, FormatConstant.GET, CommonExpressReportReq.class);
            default:
                throw new ZekeException(400, "未知药房标识");
        }
    }

    public <T extends CommonParamReq> T generateData(HttpServletRequest request, String format, Class<T> cls) {
        T t;
        switch (format) {
            case FormatConstant.GET:
            case FormatConstant.POST_URL:
                Enumeration<String> e = request.getParameterNames();
                try {
                    t = cls.newInstance();
                } catch (InstantiationException | IllegalAccessException instantiationException) {
                    instantiationException.printStackTrace();
                    log.info("反射实例异常");
                    return null;
                }
                while (e.hasMoreElements()) {
                    try {
                        String item = e.nextElement();
                        Field field;
                        try {
                            field = cls.getDeclaredField(item);
                        } catch (NoSuchFieldException | SecurityException noSuchFieldException) {
                            noSuchFieldException.printStackTrace();
                            continue;
                        }
                        field.setAccessible(true);
                        if (field.getType() == Integer.class) {
                            field.set(t, Integer.valueOf(request.getParameter(item)));
                        } else if (field.getType() == String.class) {
                            field.set(t, request.getParameter(item));
                        }
                    } catch (IllegalAccessException noSuchFieldException) {
                        noSuchFieldException.printStackTrace();
                        log.info("反射字段异常");
                    }
                }
                return t;
            case FormatConstant.POST_JSON:
                try {
                    String body = IOUtils.toString(request.getInputStream());
                    log.info("回调json参数:{}", body);
                    try {
                        t = JSON.parseObject(body, cls);
                    } catch (Exception exception) {
                        exception.printStackTrace();
                        log.info("JSON转实体类异常");
                        return null;
                    }
                    Enumeration<String> el = request.getParameterNames();
                    while (el.hasMoreElements()) {
                        String parameterName = el.nextElement();
                        log.info("回调参数-{}:{}", parameterName, request.getParameter(parameterName));
                    }
                    return t;
                } catch (IOException ioException) {
                    log.info("回调json转换失败");
                    ioException.printStackTrace();
                }
            default:
                throw new ZekeException(400, "未知编码格式");
        }
    }

    public CommonParamReq toStatusPojo() {
        return toStatusPojo(this.flag, this.request);
    }

    public CommonParamReq toExpressPojo() {
        return toExpressPojo(this.flag, this.request);
    }

    public static class FormatConstant {
        public static final String GET = "get";
        public static final String POST_URL = "postUrl";
        public static final String POST_JSON = "postJson";
    }

    public static class FlagConstant {
        //宏济堂
        public static final String HJT = "hjt";
        //大参林
        public static final String DSL = "dsl";
        //康美
        public static final String KM = "km";
        //和顺堂
        public static final String HST = "hst";
        //统一规范通用药房
        public static final String COMMON = "common";
    }
}
